﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using com.yoozoo.gta.Extension.UGUI.ScreenOrientation.Adapter;
using com.yoozoo.gta.Extension.UGUI.ScreenOrientationEx;
using UnityEditor;
using UnityEngine;
using Yoozoo.UI.YGUI;
using Object = UnityEngine.Object;

namespace com.yoozoo.gta.Extension.UGUI.Editor
{
    public class ScreenOrientionEditorTools
    {
        private static readonly string s_UIRootPath = "Assets/ResourcesAssets/Prefabs/UI";

        [MenuItem("横竖屏工具/Detector刷新")]
        public static void DetectorRefresh()
        {
            var detector = Object.FindObjectOfType<ScreenOrientDetector>();
            if (detector)
                detector.Refresh();
        }

        [MenuItem("横竖屏工具/清理ScreenOrientItem下丢失引用")]
        public static void ClearScreenOrientItemMissRef()
        {
            TraversalPath<YImageAdapter>(s_UIRootPath, (screenOrientItem) => { screenOrientItem.CollectUsedListener(); }, (traversalTAdapterItem) =>
            {
                var adapter = traversalTAdapterItem.tAdapter;
                adapter.CheckYImagePath(out _, out _);
                if (!adapter.HasComponent())
                    Object.DestroyImmediate(adapter, true);
            }, string.Empty);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
        }

        [MenuItem("横竖屏工具/清理YImage中引用")]
        public static void CleanYImageDefault(string folderPath = null)
        {
            if (folderPath == null)
                folderPath = s_UIRootPath;
            // 禁用自动刷新
            AssetDatabase.StartAssetEditing();
            var canCleanUpPrefab = new List<GameObject>();
            TraversalPath<YImageAdapter>(folderPath, null, (traversalTAdapterItem) =>
            {
                if (!traversalTAdapterItem.tAdapter.IsCanCleanup())
                {
                    var go = traversalTAdapterItem.tAdapter.gameObject;
                    var yButton = go.transform.GetComponent<YButton>();
                    var yImage = traversalTAdapterItem.tAdapter.GetComponent();
                    var result = yImage == null || (yButton && yButton.targetGraphic != null && yButton.targetGraphic.gameObject == yImage.gameObject);
                    if (!result)
                    {
                        traversalTAdapterItem.tAdapter.ClearYImage();
                        UnityEngine.Debug.Log($"YImage清理 {traversalTAdapterItem.path} 的YImage引用 {go.name}");
                        if (!canCleanUpPrefab.Contains(traversalTAdapterItem.tAdapter.gameObject))
                        {
                            canCleanUpPrefab.Add(traversalTAdapterItem.tAdapter.gameObject);
                        }
                    }
                }
            }, "清理YImage中引用");
            if (canCleanUpPrefab.Count > 0)
            {
                for (int i = 0; i < canCleanUpPrefab.Count; i++)
                {
                    var prefab = canCleanUpPrefab[i];
                    if (PrefabUtility.IsAnyPrefabInstanceRoot(prefab))
                    {
                        PrefabUtility.SavePrefabAsset(prefab);
                    }
                }
            }

            AssetDatabase.Refresh();
            // 保存所有更改
            AssetDatabase.SaveAssets();
            // 启用自动刷新
            AssetDatabase.StopAssetEditing();
        }

        [MenuItem("Assets/横竖版-清理Yimage中引用")]
        public static void CleanYImageDefaultBySelect()
        {
            // 获取当前选中的对象
            var selectedFolder = Selection.activeObject;
            // 确保有对象被选中
            if (selectedFolder == null)
            {
                Debug.Log("没有选中任何文件夹");
                return;
            }

            var path = AssetDatabase.GetAssetPath(selectedFolder);
            CleanYImageDefault(path);
        }

        [MenuItem("横竖屏工具/横竖版-检查Yimage路径")]
        public static void CheckYImagePath()
        {
            // 禁用自动刷新
            AssetDatabase.StartAssetEditing();
            TraversalPath<YImageAdapter>(s_UIRootPath, null, (traversalTAdapterItem) =>
            {
                if (!traversalTAdapterItem.tAdapter.CheckYImagePath(out _, out _))
                {
                    UnityEngine.Debug.LogError($"Prefab == : {traversalTAdapterItem.path}");
                }
            }, "检查横竖版处理错误");
            // 启用自动刷新
            AssetDatabase.StopAssetEditing();
        }

        [MenuItem("横竖屏工具/检查用隐藏YImage来做横竖版")]
        public static void CheckYImageHide(string folderPath = null)
        {
            if (folderPath == null)
                folderPath = s_UIRootPath;
            // 禁用自动刷新
            AssetDatabase.StartAssetEditing();
            TraversalPath<RectTransformAdapter>(folderPath, null, (traversalTAdapterItem) =>
            {
                var rta = traversalTAdapterItem.tAdapter;
                var go = traversalTAdapterItem.tAdapter.gameObject;
                if (rta.IsUseActiveConfig())
                {
                    var yImage = rta.GetComponent<YImage>();
                    if (yImage != null)
                        UnityEngine.Debug.LogError($"横竖版处理错误： {traversalTAdapterItem.path} 的YImage引用 {go.name}");
                }
            }, "检查横竖版处理错误");
            // 启用自动刷新
            AssetDatabase.StopAssetEditing();
        }

        [MenuItem("Assets/横竖版-检查用隐藏YImage来做横竖版")]
        public static void CheckYImageHideBySelect()
        {
            // 获取当前选中的对象
            var selectedFolder = Selection.activeObject;
            // 确保有对象被选中
            if (selectedFolder == null)
            {
                Debug.Log("没有选中任何文件夹");
                return;
            }

            var path = AssetDatabase.GetAssetPath(selectedFolder);
            CheckYImageHide(path);
        }

        /// <summary>
        /// 遍历查找返回的每一个Item数据
        /// </summary>
        /// <typeparam name="TAdapter"></typeparam>
        public struct TraversalTAdapterItem<TAdapter> where TAdapter : class
        {
            /// <summary>
            /// 目标类型
            /// </summary>
            public TAdapter tAdapter;

            /// <summary>
            /// 当前类型所在预制体的路径
            /// </summary>
            public string path;

            public GameObject prefab;
        }

        /// <summary>
        /// 遍历路径下所有
        /// </summary>
        /// <param name="folderPath"></param>
        /// <param name="screenOrientItemHandle"></param>
        /// <param name="handle"></param>
        /// <param name="logStr"></param>
        /// <typeparam name="TAdapter">指定类型</typeparam>
        private static void TraversalPath<TAdapter>(string folderPath, Action<ScreenOrientItem> screenOrientItemHandle, Action<TraversalTAdapterItem<TAdapter>> handle, string logStr)
            where TAdapter : class
        {
            var guids = AssetDatabase.FindAssets("t:prefab", new[] {folderPath});
            var totalNum = guids.Length;
            var index = 0;
            TraversalTAdapterItem<TAdapter> traversalTAdapterItem;
            foreach (var guid in guids)
            {
                index++;
                var path = AssetDatabase.GUIDToAssetPath(guid);
                var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                var item = prefab.GetComponentInChildren<ScreenOrientItem>();
                if (item != null)
                {
                    screenOrientItemHandle?.Invoke(item);
                    var handlersLists = prefab.GetComponentsInChildren<ScreenOrientationChangeHandler>(true);
                    foreach (var adapter in handlersLists)
                    {
                        if (adapter is TAdapter)
                        {
                            var tAdapter = adapter as TAdapter;
                            traversalTAdapterItem = new TraversalTAdapterItem<TAdapter>()
                            {
                                tAdapter = tAdapter,
                                path = path,
                                prefab = prefab
                            };
                            handle?.Invoke(traversalTAdapterItem);
                        }
                    }

                    EditorUtility.DisplayCancelableProgressBar(logStr, $"正在处理{index}/{totalNum}", index / (float) totalNum);
                }
            }

            // 清除进度条
            EditorUtility.ClearProgressBar();
        }

        private const string TMP_UI_SPRITE_PATH = "Assets/ResourcesAssets/UI/GUI/Tmp";

        [MenuItem("横竖屏工具/自动处理YImage种使用Arts错误路径")]
        public static void CheckYImage_IsHasArtPath()
        {
            TraversalPath<YImageAdapter>(s_UIRootPath, null, (tAdapter) =>
            {
                var prefab = tAdapter.prefab;
                var imageAdapters = prefab.GetComponentsInChildren<YImageAdapter>(true);
                for (int i = 0; i < imageAdapters.Length; i++)
                {
                    var imageAdapter = imageAdapters[i];
                    if (imageAdapter.GetComponentInParent<ParticleSystem>(true))
                        continue; // 排除特效
                    if (!imageAdapter.CheckYImagePath(out var landscapeName, out var portraitName))
                    {
                        UnityEngine.Debug.LogError($"使用了Arts下资源，在与之体内的层级关系 : {EditorExtension.HierarchyHelper.GetHierarchyPath(tAdapter.tAdapter.transform)}");
                        CopyArtSprite2Asset(tAdapter.path, landscapeName);
                        CopyArtSprite2Asset(tAdapter.path, portraitName);
                    }
                }
            }, string.Empty);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
        }

        /// <summary>
        /// 复制图片到打包路径
        /// </summary>
        /// <param name="prefabPath"></param>
        /// <param name="path"></param>
        private static void CopyArtSprite2Asset(string prefabPath, string path)
        {
            if (!string.IsNullOrEmpty(path))
            {
                //创建缓存文件夹
                if (!Directory.Exists(TMP_UI_SPRITE_PATH))
                {
                    Directory.CreateDirectory(TMP_UI_SPRITE_PATH);
                }

                var match = Regex.IsMatch(path, @"[\u4e00-\u9fff]") || path.Contains("Arts/");
                if (match)
                {
                    UnityEngine.Debug.Log($"当前处理预制体 : {prefabPath}");
                    if (!File.Exists(path))
                    {
                        UnityEngine.Debug.LogError($"发现使用Arts路径sprite但是路径下却不存在图片  {path} ,这里先手动处理不写代码了");
                        return;
                    }

                    var fileName = Path.GetFileName(path);
                    //file
                    var destFilePath = Path.GetFullPath($"{TMP_UI_SPRITE_PATH}/{fileName}");
                    File.Copy(path, destFilePath, true);
                    string yamlContent;
                    // 读取预制体文件的YAML内容
                    using (StreamReader reader = new StreamReader(prefabPath))
                    {
                        yamlContent = reader.ReadToEnd();
                    }

                    yamlContent = yamlContent.Replace(path, $"{TMP_UI_SPRITE_PATH}/{fileName}");
                    using (StreamWriter writer = new StreamWriter(prefabPath, false))
                    {
                        writer.Write(yamlContent);
                    }

                    // 刷新AssetDatabase以确保修改生效
                    AssetDatabase.Refresh();
                    AssetDatabase.SaveAssets();

                    // //meta 不能拷贝meta 需要重新生成GUID
                    // var sourceMeta = Path.GetFullPath($"{Path.GetDirectoryName(path)}/{fileName}.meta");
                    // var destFileMetaPath = Path.GetFullPath($"{TMP_UI_SPRITE_PATH}/{fileName}.meta");
                    // File.Copy(sourceMeta, destFileMetaPath, true);
                }
            }
        }
    }
}